(require 'init-funcs)

;;evil 必学
(use-package evil
    :ensure t
    :init
		(setq evil-want-keybinding nil)
		(setq evil-want-C-u-scroll t)
		(evil-mode)

      ;; https://emacs.stackexchange.com/questions/46371/how-can-i-get-ret-to-follow-org-mode-links-when-using-evil-mode
    	(with-eval-after-load 'evil-maps
        	(define-key evil-motion-state-map (kbd "RET") nil))

    :config
	(progn
        (setcdr evil-insert-state-map nil)
        (define-key evil-insert-state-map [escape] 'evil-normal-state)
        (setq-default evil-ex-search-persistent-highlight nil)
		(define-key evil-visual-state-map "p" 'evil-paste-after)
		(define-key evil-insert-state-map (kbd "C-r") 'evil-paste-from-register)
		(define-key evil-insert-state-map (kbd "C-;") 'flyspell-correct-previous)
		;;mimic "nzz" behaviou in vim
		(defadvice evil-search-next (after advice-for-evil-search-next activate)
		(evil-scroll-line-to-center (line-number-at-pos)))

		(defadvice evil-search-previous (after advice-for-evil-search-previous activate)
		(evil-scroll-line-to-center (line-number-at-pos)))

		(defun my-evil-yank ()
		(interactive)
		(save-excursion
			(call-interactively 'evil-yank))
		(backward-char))

		(define-key evil-visual-state-map (kbd "y") 'my-evil-yank)

		(define-key evil-normal-state-map
		(kbd "Y") 'zilongshanren/yank-to-end-of-line)

		(define-key evil-normal-state-map (kbd "[ SPC") (lambda () (interactive) (evil-insert-newline-above) (forward-line)))
		(define-key evil-normal-state-map (kbd "] SPC") (lambda () (interactive) (evil-insert-newline-below) (forward-line -1)))

		(define-key evil-normal-state-map (kbd "g[")
		(lambda () (interactive) (beginning-of-defun)))

		(define-key evil-normal-state-map (kbd "g]")
		(lambda () (interactive) (end-of-defun)))

		(define-key evil-normal-state-map (kbd "[ b") 'previous-buffer)
		(define-key evil-normal-state-map (kbd "] b") 'next-buffer)
		(define-key evil-motion-state-map (kbd "[ b") 'previous-buffer)
		(define-key evil-motion-state-map (kbd "] b") 'next-buffer)
		(define-key evil-normal-state-map (kbd "M-y") 'consult-yank-pop)

		(define-key evil-emacs-state-map (kbd "s-f") 'forward-word)
		(define-key evil-insert-state-map (kbd "s-f") 'forward-word)
		(define-key evil-insert-state-map (kbd "C-w") 'evil-delete-backward-word)
		(define-key evil-emacs-state-map (kbd "s-b") 'backward-word)
		(define-key evil-insert-state-map (kbd "s-b") 'backward-word)

		(define-key evil-ex-completion-map "\C-a" 'move-beginning-of-line)
		(define-key evil-ex-completion-map "\C-b" 'backward-char)
		(define-key evil-ex-completion-map "\C-k" 'kill-line)

		(define-key minibuffer-local-map (kbd "C-w") 'evil-delete-backward-word)

		(define-key evil-visual-state-map (kbd "C-r") 'zilongshanren/evil-quick-replace)


		;; Don't move back the cursor one position when exiting insert mode
		(setq evil-move-cursor-back nil)

		(define-key evil-emacs-state-map (kbd "C-w") 'evil-delete-backward-word)

		(evil-define-key 'emacs term-raw-map (kbd "C-w") 'evil-delete-backward-word)


		(setq evil-normal-state-tag   (propertize "[N]" 'face '((:background "DarkGoldenrod2" :foreground "black")))
			evil-emacs-state-tag    (propertize "[E]" 'face '((:background "SkyBlue2" :foreground "black")))
			evil-insert-state-tag   (propertize "[I]" 'face '((:background "chartreuse3") :foreground "white"))
			evil-motion-state-tag   (propertize "[M]" 'face '((:background "plum3") :foreground "white"))
			evil-visual-state-tag   (propertize "[V]" 'face '((:background "gray" :foreground "black")))
			evil-operator-state-tag (propertize "[O]" 'face '((:background "purple"))))
		(setq evil-insert-state-cursor '("chartreuse3" bar))
		(define-key evil-insert-state-map (kbd "C-z") 'evil-emacs-state)

	)
)

;; anzu for evil-mode

(use-package evil-anzu
	:ensure t
	:after evil
	:diminish
	:demand t
	:init
	(global-anzu-mode t))

(use-package evil-collection
	:ensure t
	:demand t
	:config
	(setq evil-collection-mode-list (remove 'lispy evil-collection-mode-list))
	(evil-collection-init)

	(cl-loop for (mode . state) in
			'((org-agenda-mode . normal)
				(Custom-mode . emacs)
				(makey-key-mode . motion))
			do (evil-set-initial-state mode state))


	(evil-define-key 'normal dired-mode-map
	(kbd "<RET>") 'dired-find-alternate-file
	(kbd "C-k") 'dired-up-directory
	"`" 'dired-open-term
	"o" 'dired-find-file-other-window
	"s" 'hydra-dired-quick-sort/body
	"z" 'dired-get-size
	"!" 'zilongshanren/do-shell-and-copy-to-kill-ring
	")" 'dired-omit-mode)

	(when sys/win32p
	(evil-define-key 'normal dired-mode-map
		"s" 'dired-sort-toggle-or-edit))

	(evil-define-key 'normal help-mode-map
	"o" 'link-hint-open-link)
)

;;回退
(use-package undo-tree
	:ensure t
	:diminish
	:init
	(global-undo-tree-mode 1)
  	(setq undo-tree-auto-save-history nil)
  	(evil-set-undo-system 'undo-tree)
)

;;快速修改引号、括号
(use-package evil-surround
	:ensure t
	:init
	(global-evil-surround-mode 1)
)

;;多行屏蔽或解除屏蔽
(use-package evil-nerd-commenter
	:ensure t
	:init
	(define-key evil-normal-state-map (kbd ",/") 'evilnc-comment-or-uncomment-lines)
	(define-key evil-visual-state-map (kbd ",/") 'evilnc-comment-or-uncomment-lines)
	;; (evilnc-default-hotkeys)
)

;; 小范围查找
(use-package evil-snipe
	:ensure t
	:diminish
	:init
	(evil-snipe-mode +1)
	(evil-snipe-override-mode +1)
)

(provide 'init-evil)